# -*- coding: utf-8 -*-
from odoo import models, fields, api, tools, _
from odoo.exceptions import ValidationError, Warning
from datetime import datetime
from . import config_item

ORDER_STATE = [
    ('doing', '进行中'),
    ('finished', '已完成')
]

CONTRACT_STATUS = [('new', '新建'), ('execute', '执行'), ('due', '过期')]

class LineOperator(models.Model):
    _name = "tyibs.main.line.operator"
    name = fields.Char(string=u"网络运营商",required=True)
    _sql_constraints = [("unique_name", "unique(name)", u"名字有重复！")]

class LiftPart(models.Model):
    _name = "tyibs.main.lift.part"
    _rec_name = "category_part_id"

    lift_id = fields.Many2one("tyibs.base.lift", string=u"电梯", required=True)
    maintenance_company_id = fields.Many2one("tyibs.base.maintenance.company",string=u"维保公司",related="lift_id.maintenance_company_id",store=True)
    category_part_id = fields.Many2one("tyibs.main.lift.big.category.part", string="标准部位", required=True)
    rfid_code = fields.Char(string=u"RFID码", size=100)
    qrcode = fields.Char(string="二维码", size=100)

    _sql_constraints = [
        ("unique_rfid_code", "unique(rfid_code)", u"RFID码有重复！"),
        ("unique_qrcode", "unique(qrcode)", u"二维码有重复！")
    ]


class UseCompany(models.Model):
    # 使用单位扩展
    _inherit = "tyibs.base.lift.use.company"

    rfid_code = fields.Char(string=u"RFID码")
    qr_code = fields.Char(string=u"二维码")

    _sql_constraints = [
        ("unique_rfid_code", "unique(rfid_code)", u"RFID码有重复！"),
        ("unique_qr_code", "unique(qr_code)", u"二维码有重复！")
    ]


class Lift(models.Model):
    """
    电梯扩展
    """
    _inherit = "tyibs.base.lift"

    lift_part_ids = fields.One2many("tyibs.main.lift.part", "lift_id", string=u"电梯部位")
    main_dis_list_ids = fields.Many2many("tyibs.main.distribution.list","tyibs_main_lift_dis_list_rel","lift_id","list_id",string=u"分配单")
    dis_list_count = fields.Integer(string=u"分配单数",store=True,compute="_compute_dis_list_count")

    change_main_company = fields.Char(string=u"用来触发维保公司改变",compute="_compute_change_main_company_id",store=True)
    line_operator_ids = fields.Many2many('tyibs.main.line.operator','tyibs_lift_line_operator_rel','line_operator_id','lift_id',string=u"网络运营商")

    normal_main_count = fields.Integer(string=u"正常维保数量")
    over_due_main_count = fields.Integer(string=u"超期维保数量")
    over_due_not_main_count = fields.Integer(string=u"超期未维保数量")

    @api.depends('maintenance_company_id')
    def _compute_change_main_company_id(self):
        # 当电梯的维保公司改变的时候触发
        for item in self:
            # 删除名下所有的人员分配单
            super(Lift,item).write({'main_dis_list_ids':[(5,False,False)]})
            item.change_main_company = True

    @api.depends('main_dis_list_ids')
    def _compute_dis_list_count(self):
        # 当产生新分配单的时候，更新分配单数量
        for item in self:
            item.dis_list_count = len(item.main_dis_list_ids)

    @api.onchange("big_category_id")
    def _onchange_big_category_id(self):
        self.lift_part_ids = False
        part_ids = [{'lift_id': self, 'category_part_id': item} for item in self.big_category_id.part_ids]
        self.lift_part_ids = part_ids

    @api.model
    def create(self, vals):
        lift_part_ids = []
        if vals.get("big_category_id", False):
            part_ids = self.env["tyibs.main.lift.big.category.part"].search([("big_category_id", "=", vals.get("big_category_id"))])
            lift_part_ids = [(0, False, {'category_part_id': item.id}) for item in part_ids]
        vals["lift_part_ids"] = lift_part_ids
        lift_part_ids = vals.get("lift_part_ids", False)
        category_part_ids = [item[2].get("category_part_id") for item in (lift_part_ids if lift_part_ids else [])]
        if len(category_part_ids) != len(list(set(category_part_ids))):
            raise Warning(u"有重复的标准部位！")
        return super(Lift, self).create(vals)

    @api.multi
    def unlink(self):
        self.lift_part_ids.unlink()
        super(Lift, self).unlink()

    @api.multi
    def action_open_lift_info_widget(self):
        """
        显示电梯综合看板
        :return:
        """
        self.ensure_one()
        action = self.env.ref("lift_main.action_tyibs_main_all_lift_1").read()[0]
        return action

    @api.multi
    def action_show_lift_detail(self):
        """
        显示电梯详细页面，即原生的表单页面
        """
        self.ensure_one()
        action = self.env.ref("lift_main.action_tyibs_main_lift_detail").read()[0]
        action.update({'res_id':self.id,'name':u'电梯详情'})
        return action

    @api.model 
    def get_app_sync_data(self, maintenance_company_id):
        """
        @param maintenance_company_id 维保公司Id
        返回APP所需要的缓存数据：包括电梯、部位、检查项
        """
        result = {
            'lift_items':[],
            'check_items':[],
            'lift_part_items':[]
        }

        lift_items = self.sudo().search([('maintenance_company_id', '=', maintenance_company_id)])
        print lift_items
        lift_part_items = lift_items.mapped('lift_part_ids')

        check_item_domain = ['|',('enterprise_id','=',maintenance_company_id),('scope_type','!=','2')]
        check_items = self.env['tyibs.main.standard.check.item'].search(check_item_domain)

        result['lift_items'] = [{
            'id': item.id,
            'code': item.code,
            'register_code': item.register_code,
            'rfid_code': item.rfid_code,
            'qrcode': item.code,
            'maintenance_company_id':item.maintenance_company_id.id,
            'maintenance_company_name': item.maintenance_company_id.name,
            'use_company_id': item.use_company_id.id,
            'use_company_name': item.use_company_id.name,
            'big_category_id': item.big_category_id.id,
            'big_category_name': item.big_category_id.name,
            'use_address': item.use_address
        } for item in lift_items]

        check_item_types = dict(config_item.CHECK_ITEM_TYPE)
        check_item_scope_types = dict(config_item.CHECK_ITEM_SCOPE_TYPE)

        result['check_items'] = [{
            'id': item.id,
            'lift_big_category_id': item.lift_big_category_id.id,
            'lift_big_category_name': item.lift_big_category_id.name,
            'check_item_type': item.check_item_type,
            'check_item_type_name': check_item_types.get(int(item.check_item_type),''),
            'scope_type': item.scope_type,
            'scope_type_name': check_item_scope_types.get(item.scope_type,''),
            'content': item.content,
            'require': item.require,
            'remark': item.remark,
            'standard_part_id': item.part_id.id,
            #'standard_part_name': itme.part_id.name
        } for item in check_items]
        
        result['lift_part_items'] = [{
            'id': item.id,
            'lift_id':item.lift_id.id,
            'standard_part_id':item.category_part_id.id,
            'standard_part_name': item.category_part_id.name,
            'rfid_code': item.rfid_code,
            'qrcode': item.qrcode
        } for item in lift_part_items]

        return result


class Contract(models.Model):
    """
    维保合同
    """

    _name = "tyibs.main.contract"
    _rec_name = "serial_number"
    _order = "id desc"

    serial_number = fields.Char(string=u"编号", default=lambda self: self.env["ir.sequence"].next_by_code("tyibs.main.contract.number.sequence"), required=True, readonly=True)
    code = fields.Char(string=u"合同号", size=50, required=True)
    maintenance_company_id = fields.Many2one("tyibs.base.maintenance.company", string=u"维保公司", required=True, default=lambda self: self.env.user.main_company_id.id)
    use_company_id = fields.Many2one("tyibs.base.lift.use.company", string=u"使用单位", required=True)
    # safety_manager = fields.Many2one("tyibs.base.maintenance.company.employee", string=u"安全管理员", domain="[('enterprise_id', '=', maintenance_company_id)]")
    # safety_manager_tel = fields.Char(related="safety_manager.phone", store=True, string=u"管理员电话")
    # safety_manager_mobile = fields.Char(related="safety_manager.mobile", store=True, string=u"管理员手机")
    # main_manager_id = fields.Many2one("tyibs.base.maintenance.company.employee", string=u"负责人", domain="[('enterprise_id', '=', maintenance_company_id)]")

    is_free = fields.Boolean(string=u"免保合同")
    main_type = fields.Selection([('contract','合同维保'),('original','原厂维保')], string=u"维保类型", default="contract", required=True)

    pay_method_id = fields.Many2one("tyibs.main.pay.method", string="付款方式")
    free_scope_id = fields.Many2one("tyibs.main.free.scope", string="免费范围")
    contract_money = fields.Char(string=u"合同金额")
    start = fields.Date(string=u"合同开始日期", required=True)
    end = fields.Date(string=u"合同结束日期", required=True)
    sign_date = fields.Date(string=u"签署日期", required=True)
    generate_time = fields.Datetime(string=u"制单时间", default=datetime.utcnow())
    status = fields.Selection(CONTRACT_STATUS, string=u"合同状态", default="new")

    remark = fields.Text(string=u"备注")
    attachment_ids = fields.Many2many("ir.attachment", string=u"附件", domain="[('res_model','=','tyibs.main.contract'), ('res_id','=',id)]",required=True)

    # 电梯过滤：1 合同使用单位 2 没有维保公司 3 已经注册的 4 电梯必须要有使用单位
    # 10月22日放开
    lift_ids = fields.Many2many("tyibs.base.lift", "tyibs_base_lift_main_contract_rel", "lift_id", "contract_id", string=u"维保电梯",
                                domain="[('use_company_id', '!=', False),('use_company_id', '=', use_company_id), ('maintenance_company_id', '=', False),('register_status','=','registered')]", required=True)
    # lift_ids = fields.Many2many("tyibs.base.lift", "tyibs_base_lift_main_contract_rel", "lift_id", "contract_id",
    #                             string=u"维保电梯",
    #                             domain="[('use_company_id', '!=', False),('use_company_id', '=', use_company_id),('register_status','=','registered')]",
    #                             required=True)
    lift_count = fields.Integer(string=u"电梯数量", compute="_compute_lift_count", store=True)

    apply_status = fields.Selection([('pending', '待审核'), ('approved', '审核通过'), ('reject', '审核未通过')], string=u"处理状态", default="pending")
    check_log_ids = fields.Many2many("tyibs.base.common.log", domain="[('res_model', '=', 'tyibs.main.contract'), ('res_id', '=', id)]", string=u"审核记录")


    _sql_constraints = [
        ("unique_serial_number", "unique(serial_number)", u"编号已存在，请核对后重新输入！"),
        ("unique_code", "unique(code)", u"合同号已存在，请核对后重新输入！")
    ]


    @api.depends("lift_ids")
    def _compute_lift_count(self):
        self.lift_count = len(self.lift_ids)

    @api.constrains("start", "end")
    def _constrains_start_end(self):
        if self.start and self.end and self.start > self.end:
            raise ValidationError(u"合同开始日期必须在合同结束日期之前")

    @api.one
    def approve(self):
        """
        审核通过
        :return:
        """
        # 绑定维保公司
        self.lift_ids.sudo().write({'maintenance_company_id': self.maintenance_company_id.id})
        # 变更合同状态、写入日志
        self.origin_write({
            'status': 'execute',
            'apply_status': 'approved',
            'check_log_ids': [(0, False, {
                'res_model': self._name,
                'res_id': self.id,
                'user_id': self.env.uid,
                'content': u"审核通过",
                'time': datetime.utcnow()
            })]
        })

    @api.one
    def abort(self):
        self.past_due(
            check_log_ids = [(0, False, {
                'res_model': self._name,
                'res_id': self.id,
                'user_id': self.env.uid,
                'content': u"终止合同",
                'time': datetime.utcnow()
            })]
        )

    @api.one
    def past_due(self, **vals):
        """
        设置合同为过期
        :return:
        """
        vals["status"] = "due"
        self.origin_write(vals)
        # 删除电梯上的维保单位信息，更新电梯上的上家维保单位
        self.lift_ids.write({
            "maintenance_company_id": False,
            "last_maintenance_company_id": self.maintenance_company_id.id,
            "maintenance_site_id": False,
            "maintenance_salvager_id": False,
            "maintenance_salvager_mobile": False
        })
        return True

    @api.multi
    def write(self, vals):
        """
        修改内容后，将审核状态改为待审核，要重新审核
        :param vals:
        :return:
        """

        system_group_id = self.env.ref("base.group_system").id
        access_ids = self.env.user.groups_id.ids
        if self.apply_status == "approved" and system_group_id not in access_ids:
            # 非系统管理员修改审核通过的合同
            raise Warning(u"审核通过的合同不可以修改！")
        vals["apply_status"] = "pending"
        return super(Contract, self).write(vals)

    def origin_write(self, vals):
        """
        直接走父类write方法：解决审核通过的时候会触发write状态变更为待审核的BUG
        :param vals:
        :return:git
        """
        return super(Contract, self).write(vals)

    @api.model
    def search(self, args, offset=0, limit=None, order=None, count=False):
        context = self._context or {}
        if context.get("search_from", False) == "main_menu":
            args.append(("maintenance_company_id", "=", self.env.user.main_company_id.id))
        # elif context.get("search_from", False) == "qs_area":
        #     args.append(("use_company_id.area_id", "=", self.env.user.qs_company_id.area_id.id))
        elif context.get("search_from", False) == "use":
            args.append(("use_company_id", "=", self.env.user.use_company_id.id))
        return super(Contract, self).search(args, offset, limit, order, count)


class MaintenanceCompany(models.Model):
    """
    维保公司扩展
    """
    _inherit = "tyibs.base.maintenance.company"

    dis_list_ids = fields.One2many("tyibs.main.distribution.list","maintenance_company_id",string=u"分配单")
    contract_ids = fields.One2many("tyibs.main.contract", "maintenance_company_id", string=u"合同")

class MainDistributionList(models.Model):
    """
    维保公司人员分配单
    """
    _name = "tyibs.main.distribution.list"

    name = fields.Char(string=u"分配单名称",required=True)
    maintenance_company_id = fields.Many2one("tyibs.base.maintenance.company",string=u"维保公司",required=True, default=lambda self: self.env.user.main_company_id.id)
    dept_ids = fields.Many2many("tyibs.base.maintenance.company.department","tyibs_main_dislist_department_rel","list_id","dept_id",
                                domain="[('enterprise_id','=',maintenance_company_id)]",string=u"分组")
    employee_ids = fields.Many2many("tyibs.base.maintenance.company.employee", "tyibs_main_dislist_employee_rel","list_id","employee_id",
                                    string=u"组员")
                                    # string=u"组员", domain="[('department_id','in',[dept_ids[0][2]] )]")
    
    # 不能是一对多关系：原因： 1 列别只能创建不能查 2 一对多列表删除是实体删除，不能删 
    lift_ids = fields.Many2many("tyibs.base.lift","tyibs_main_lift_dis_list_rel","list_id","lift_id",
                                string=u"分配的电梯",
                                domain="[('maintenance_company_id','=',maintenance_company_id),'|',('dis_list_count','=',False),('dis_list_count','=',0)]"
                                )

    # [('department_id','in',[dept_ids[0][2]])]:[0][2]这里有个BUG,如果没有组，选择员工会报错，下面这方法适合在FORM，List会全改，慎用
    # 这方法还有个BUG,重新打开不会触发onchange,坑的很，可以给一个默认
    @api.onchange('dept_ids','maintenance_company_id','do_change')
    def change_dept_ids(self):
        if self.dept_ids:
            return {'domain':{'employee_ids':[('department_id','in',self.dept_ids.ids)]}}
        else:
            return {'domain':{'employee_ids':[('enterprise_id','=',self.maintenance_company_id.id)]}}



# PLAN_STATES = [
#     ('new', '新建'),
#     ('runing', '执行' ),
#     ('stop', '停止' ),
#     ('finished', '完成' ),
# ]


# class Plan(models.Model):
#     """
#     维保计划
#     """
#     _name = "tyibs.main.plan"
#     _rec_name = "so"

#     so = fields.Char(string=u"编号", size=100, required=True)
#     use_company_id = fields.Many2one("tyibs.base.lift.use.company", string=u"签约使用客户", required=True)
#     contract_id = fields.Many2one("tyibs.main.contract", string=u"合同", required=True,
#                                   domain="[('use_company_id', '=', use_company_id), ('apply_status','=','approved')]")
#     maintenance_company_id = fields.Many2one(related="contract_id.maintenance_company_id", store=True)
#     contract_start = fields.Date(string=u"合同开始日期")
#     contract_end = fields.Date(string=u"合同结束日期")
#     start = fields.Date(string=u"开始日期", required=True)
#     end = fields.Date(string=u"结束日期", required=True)
#     dept_id = fields.Many2one("tyibs.base.maintenance.company.department", string=u"服务班级", required=True,domain="[('enterprise_id','=',maintenance_company_id)]")
#     employee_ids = fields.Many2many("tyibs.base.maintenance.company.employee", string=u"班级成员", domain="[('department_id','=',dept_id)]", required=True)
#     lift_ids = fields.Many2many("tyibs.base.lift", string=u"选择电梯", required=True)
#     state = fields.Selection(PLAN_STATES, string=u"状态", default="new")
#     remark = fields.Text(string=u"备注")

#     @api.onchange("contract_id")
#     def _on_change_contract_id(self):
#         if not self.contract_id:
#             return {}
#         left_lift_ids = self.contract_id.lift_ids
#         for row in self.contract_id.plan_ids.filtered(lambda record: record.state != 'stop'):
#             left_lift_ids = left_lift_ids - row.lift_ids
#         # 维保计划状态为停止时，其下的电梯可以再被选择
#         if not left_lift_ids.ids:
#             return {
#                 'value': {
#                     'contract_id': '',
#                 },
#                 'warning': {
#                     'title': '出错了!',
#                     'message': '此合同下所有电梯都已经分配完成!',
#                 }
#             }
#         return {
#             'value': {
#                 'contract_start': self.contract_id.start,
#                 'contract_end': self.contract_id.end,
#                 'start': self.contract_id.start,
#                 'end': self.contract_id.end,
#             },
#             'domain':
#                 {'lift_ids': [('id', 'in', left_lift_ids.ids)]}
#         }


# class MaintenanceWorkOrder(models.Model):
#     """
#     维保工单
#     """
#     _name = "tyibs.main.work.order"
#     _order = "id desc"

#     name = fields.Char(string=u"工单编号",required=True)
#     contract_id = fields.Many2one("tyibs.main.contract",string=u"合同",required=True)
#     use_company_id = fields.Many2one("tyibs.base.lift.use.company", string=u"签约使用客户", required=True)
#     maintenance_company_id = fields.Many2one("tyibs.base.maintenance.company",string=u"维保公司",required=True)
#     dept_id = fields.Many2one("tyibs.base.maintenance.company.department", string=u"服务班级", required=True,domain="[('enterprise_id','=',maintenance_company_id)]")
#     employee_ids = fields.Many2many("tyibs.base.maintenance.company.employee","tyibs_mainemployee_work_order_rel", string=u"班级成员", domain="[('department_id','=',dept_id)]", required=True)
#     lift_id = fields.Many2one("tyibs.danbase.lift",string=u"所属电梯",required=True)

#     plan_date = fields.Date(string=u"计划执行时间")
#     do_date = fields.Date(string=u"实际执行时间")
#     order_state = fields.Selection([('tostart',u'尚未开始'),('start',u'签到开始'),('finish',u'完成'),('unfinish',u'失败')],
#                                     string=u"工单状态",default='tostart')
#     finish_state = fields.Selection([('tostart',u'尚未开始'),('start',u'签到开始'),('over_tostart',u'超期'),('finish_early',u'提前完成'),('finish_normal',u'完成'),('finish_late',u'超期已完成'),('unfinish_un',u'超期未完成')],
#                                     string=u"完成情况",default='tostart')
#     order_type = fields.Selection(config_item.CHECK_ITEM_TYPE,string=u"工单类型",required=True)
#     type_num = fields.Integer(string=u"类型值",store=True,compute="_compute_type_num")
#     check_item_ids = fields.One2many("tyibs.main.work.order.check.item",'order_id',string=u"维保项")


#     @api.depends("order_type")
#     def _compute_type_num(self):
#         # 定义检查项维保类型的值，1是为了全局配置各类型的时间，2是为了方便查找
#         self.type_num = config_item.CHECK_ITEM_VALUE[self.order_type]

# class MaintenanceWorkOrderCheckItem(models.Model):
#     """
#     维保项
#     """
#     _name = "tyibs.main.work.order.check.item"
#     _rec_name = "content"

#     content = fields.Char(string=u"保养项目",required=True)
#     order_id = fields.Many2one("tyibs.main.work.order",string=u"所属工单",required=True)
#     contract_id = fields.Many2one("tyibs.main.contract",string=u"合同",required=True)
#     lift_id = fields.Many2one("tyibs.base.lift",string=u"所属电梯")
#     lift_big_category_id = fields.Many2one("tyibs.base.lift.big.category", string=u"所属大类", required=True)
#     part_id = fields.Many2one("tyibs.main.lift.big.category.part", string=u"所属部位", required=True,
#                               domain="[('big_category_id', '=', lift_big_category_id)]")
#     check_item_type = fields.Selection(config_item.CHECK_ITEM_TYPE, string=u"维保类型", required=True)
#     type_num = fields.Integer(string=u"类型值",store=True,compute="_compute_type_num")
#     require = fields.Char(string=u"基本要求")
#     remark = fields.Text(string=u"备注")

#     @api.depends("check_item_type")
#     def _compute_type_num(self):
#         # 定义检查项维保类型的值，1是为了全局配置各类型的时间，2是为了方便查找
#         self.type_num = config_item.CHECK_ITEM_VALUE[self.check_item_type]
